using YMJake.Flowable.ExternalWorker.Client.AspNetCore.Pipeline;
using YMJake.Flowable.ExternalWorker.Client.Core.Client;

namespace YMJake.Flowable.ExternalWorker.Client.Sample.Handlers;

/// <summary>
/// Handler for processing orders using the pipeline pattern
/// </summary>
public class OrderProcessingHandler : IWorkerHandler
{
    private readonly ILogger<OrderProcessingHandler> _logger;

    public OrderProcessingHandler(ILogger<OrderProcessingHandler> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task HandleAsync(IWorkerPipelineContext context)
    {
        _logger.LogInformation("Processing order job {JobId}", context.Job.Id);

        try
        {
            // Get order data from job variables
            var orderId = GetVariable<string>(context.Job, "orderId") ?? "unknown";
            var amount = GetVariable<double>(context.Job, "amount");

            _logger.LogInformation("Processing order {OrderId} with amount {Amount}", orderId, amount);

            // Simulate processing
            await Task.Delay(1000, context.CancellationToken);

            // Set the result
            context.Result = context.ResultBuilder.Success()
                .Variable("processedAt", DateTime.UtcNow)
                .Variable("status", "completed")
                .Variable("processedAmount", amount)
                .Variable("orderId", orderId);

            _logger.LogInformation("Successfully processed order {OrderId}", orderId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to process order job {JobId}", context.Job.Id);
            
            context.Result = context.ResultBuilder.Failure()
                .Error(ex)
                .WithRetries(3);
        }
    }

    private T? GetVariable<T>(IAcquiredExternalWorkerJob job, string key)
    {
        if (job.Variables.TryGetValue(key, out var value) && value is T typedValue)
        {
            return typedValue;
        }
        return default;
    }
}